package top.houry.im.server.netty;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;
import top.houry.im.server.proto.ImMessage;
import top.houry.im.server.handler.ImServerMsgTypeHandler;
import top.houry.im.server.util.ImServerSpringUtils;

/**
 * @Desc 配置netty-handler
 * @Author houry
 * @Date 2021/3/2 9:30
 **/
@Slf4j
public class ImServerNettyHandler extends SimpleChannelInboundHandler<ImMessage.Server> {

    @Override
    public void channelRead0(ChannelHandlerContext ctx, ImMessage.Server server) throws Exception {
        try {
            String msgType = server.getMsgType();
            if (StrUtil.isBlank(msgType)) {
                log.info("[ImServerNettyHandler]-[channelRead0]-[msgType:{}]-[不存在]", msgType);
                return;
            }
            ImServerMsgTypeHandler typeService = ImServerSpringUtils.getBean(msgType);
            if (ObjectUtil.isNull(typeService)) {
                log.info("[ImServerNettyHandler]-[channelRead0]-[根据msgType:{}]-[没有找到对应的typeService]", msgType);
                return;
            }
            typeService.processImMsg(server, ctx);
        } catch (Exception e) {
            ctx.close();
            log.error("[EXCEPTION]-[ImServerNettyHandler]-[channelRead0]", e);
        }
    }


    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        log.info("[ImServerNettyHandler]-[handlerAdded]-[{}]", ctx.channel().toString());
    }


    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        log.info("[ImServerNettyHandler]-[handlerRemoved]-[{}]", ctx.channel().toString());
    }


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("[ImServerNettyHandler]-[exceptionCaught]-[Exception]", cause);
        ctx.channel().close();
    }


    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            switch (event.state()) {
                case READER_IDLE:
                    log.info("[ImServerNettyHandler]-[userEventTriggered]-[没有接收到：{}]-[的信息心跳信息，将断开连接回收资源]", ctx.toString());
                    ctx.channel().close();
                    break;
                case WRITER_IDLE:
                    log.info("[ImServerNettyHandler]-[userEventTriggered]-[写空闲]");
                    break;
                case ALL_IDLE:
                    log.info("[ImServerNettyHandler]-[userEventTriggered]-[读写空闲]");
                    break;
                default:
                    log.info("[ImServerNettyHandler]-[userEventTriggered]-[非法状态]");
                    throw new IllegalStateException("非法状态！");
            }
        }
    }


}
